using Microsoft.Extensions.Logging;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Infrastructure.Data;
using SumerCoreDevOps.Infrastructure.Security;
using SumerCoreDevOps.Infrastructure.Utilities;

namespace SumerCoreDevOps.Infrastructure.Configuration;

/// <summary>
/// 系统配置管理器
/// </summary>
public class SystemConfigManager
{
    private readonly FreeSQLProvider _dbProvider;
    private readonly ILogger<SystemConfigManager> _logger;
    private ConfigurationNotificationService? _notificationService;

    public SystemConfigManager(FreeSQLProvider dbProvider, ILogger<SystemConfigManager> logger)
    {
        _dbProvider = dbProvider;
        _logger = logger;
    }

    /// <summary>
    /// 设置配置通知服务（延迟注入以避免循环依赖）
    /// </summary>
    public void SetNotificationService(ConfigurationNotificationService notificationService)
    {
        _notificationService = notificationService;
    }

    /// <summary>
    /// 初始化默认配置
    /// </summary>
    public async Task InitializeDefaultConfigsAsync()
    {
        var defaultConfigs = new List<SystemConfig>
        {
            // ===== 网络配置 =====
            new SystemConfig
            {
                ConfigKey = "ControlApiPort",
                ConfigValue = "5000",
                ConfigType = "Int",
                Category = "Network",
                Description = "控制面板 API 端口",
                RequiresRestart = true,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 1
            },
            new SystemConfig
            {
                ConfigKey = "TcpServerPort",
                ConfigValue = "9090",
                ConfigType = "Int",
                Category = "Network",
                Description = "执行节点连接的 TCP 服务器端口",
                RequiresRestart = true,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 2
            },
            new SystemConfig
            {
                ConfigKey = "NodeDefaultPort",
                ConfigValue = "9091",
                ConfigType = "Int",
                Category = "Network",
                Description = "执行节点默认端口",
                RequiresRestart = false,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 3
            },

            // ===== 系统配置 =====
            new SystemConfig
            {
                ConfigKey = "MaxConcurrentTasks",
                ConfigValue = "10",
                ConfigType = "Int",
                Category = "System",
                Description = "最大并发任务数",
                RequiresRestart = false,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 10
            },
            new SystemConfig
            {
                ConfigKey = "TaskTimeoutMinutes",
                ConfigValue = "60",
                ConfigType = "Int",
                Category = "System",
                Description = "任务超时时间（分钟）",
                RequiresRestart = false,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 11
            },

            // ===== 构建产物配置 =====
            new SystemConfig
            {
                ConfigKey = "Artifact.DefaultRetentionDays",
                ConfigValue = "30",
                ConfigType = "Int",
                Category = "Artifact",
                Description = "构建产物默认保留天数（工作流未指定时使用）",
                RequiresRestart = false,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 12
            },
            new SystemConfig
            {
                ConfigKey = "Artifact.CleanupIntervalHours",
                ConfigValue = "24",
                ConfigType = "Int",
                Category = "Artifact",
                Description = "产物清理任务执行间隔（小时）",
                RequiresRestart = false,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 13
            },

            // ===== Git 配置 =====
            new SystemConfig
            {
                ConfigKey = "Git.UserName",
                ConfigValue = "SumerCore DevOps",
                ConfigType = "String",
                Category = "Git",
                Description = "Git 操作时的用户名（用于 commit 签名）",
                RequiresRestart = false,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 20
            },
            new SystemConfig
            {
                ConfigKey = "Git.UserEmail",
                ConfigValue = "devops@sumer.com",
                ConfigType = "String",
                Category = "Git",
                Description = "Git 操作时的用户邮箱（用于 commit 签名）",
                RequiresRestart = false,
                IsSystem = true,
                IsSensitive = false,
                SortOrder = 21
            }

            // ===== Git 仓库凭据配置示例 =====
            // 注意：这些是示例，实际使用时应通过 API 创建，并设置 IsSensitive = true
            //
            // Git.DefaultUsername - Git 默认用户名（用于仓库认证）
            // Git.DefaultPassword - Git 默认密码或 Personal Access Token（加密存储）
            // Git.DefaultRepositoryUrl - 默认 Git 仓库 URL
            //
            // 使用示例：
            // POST /api/SystemConfig
            // {
            //   "configKey": "Git.DefaultUsername",
            //   "configValue": "git-bot",
            //   "category": "Git",
            //   "isSensitive": false
            // }
            //
            // POST /api/SystemConfig
            // {
            //   "configKey": "Git.DefaultPassword",
            //   "configValue": "ghp_xxxxxxxxxxxxxxxxxxxx",  // GitHub Personal Access Token
            //   "category": "Git",
            //   "isSensitive": true  // 自动加密存储
            // }

            // 注意：不在这里添加敏感配置（如加密密钥、密码等）的默认值
            // 敏感配置应该由管理员手动创建或通过环境变量设置
        };

        foreach (var config in defaultConfigs)
        {
            var existing = await _dbProvider.Orm.Select<SystemConfig>()
                .Where(c => c.ConfigKey == config.ConfigKey)
                .FirstAsync();

            if (existing == null)
            {
                await _dbProvider.Orm.Insert(config).ExecuteAffrowsAsync();
                _logger.LogInformation("初始化系统配置: {ConfigKey} = {ConfigValue}",
                    config.ConfigKey, config.IsSensitive ? "********" : config.ConfigValue);
            }
        }
    }

    /// <summary>
    /// 获取配置值
    /// </summary>
    public async Task<string?> GetConfigValueAsync(string configKey)
    {
        var config = await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.ConfigKey == configKey)
            .FirstAsync();

        return config?.ConfigValue;
    }

    /// <summary>
    /// 获取配置值（带默认值）
    /// </summary>
    public async Task<string> GetConfigValueAsync(string configKey, string defaultValue)
    {
        var value = await GetConfigValueAsync(configKey);
        return value ?? defaultValue;
    }

    /// <summary>
    /// 获取整型配置值
    /// </summary>
    public async Task<int> GetIntConfigAsync(string configKey, int defaultValue)
    {
        var value = await GetConfigValueAsync(configKey);
        if (string.IsNullOrEmpty(value))
        {
            return defaultValue;
        }

        return int.TryParse(value, out var result) ? result : defaultValue;
    }

    /// <summary>
    /// 获取布尔型配置值
    /// </summary>
    public async Task<bool> GetBoolConfigAsync(string configKey, bool defaultValue)
    {
        var value = await GetConfigValueAsync(configKey);
        if (string.IsNullOrEmpty(value))
        {
            return defaultValue;
        }

        return bool.TryParse(value, out var result) ? result : defaultValue;
    }

    /// <summary>
    /// 获取配置实体
    /// </summary>
    public async Task<SystemConfig?> GetConfigAsync(string configKey)
    {
        return await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.ConfigKey == configKey)
            .FirstAsync();
    }

    /// <summary>
    /// 获取所有配置
    /// </summary>
    public async Task<List<SystemConfig>> GetAllConfigsAsync()
    {
        return await _dbProvider.Orm.Select<SystemConfig>()
            .OrderBy(c => c.Category)
            .OrderBy(c => c.SortOrder)
            .ToListAsync();
    }

    /// <summary>
    /// 按分类获取配置
    /// </summary>
    public async Task<List<SystemConfig>> GetConfigsByCategoryAsync(string category)
    {
        return await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.Category == category)
            .OrderBy(c => c.SortOrder)
            .ToListAsync();
    }

    /// <summary>
    /// 更新配置
    /// </summary>
    public async Task<bool> UpdateConfigAsync(string configKey, string configValue, string? updatedBy = null)
    {
        var config = await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.ConfigKey == configKey)
            .FirstAsync();

        if (config == null)
        {
            _logger.LogWarning("配置不存在: {ConfigKey}", configKey);
            return false;
        }

        // 验证值的类型
        if (!ValidateConfigValue(config.ConfigType, configValue))
        {
            throw new InvalidOperationException($"配置值类型不匹配，期望类型：{config.ConfigType}");
        }

        // 特殊验证：端口配置
        if (IsPortConfig(configKey))
        {
            ValidatePortConfig(configKey, configValue);
        }

        var oldValue = config.ConfigValue;

        // 如果是敏感信息，加密存储；否则直接存储
        var valueToStore = config.IsSensitive ? EncryptionHelper.Encrypt(configValue) : configValue;

        config.ConfigValue = valueToStore;
        config.UpdatedAt = DateTime.UtcNow;
        config.UpdatedBy = updatedBy;

        await _dbProvider.Orm.Update<SystemConfig>()
            .SetSource(config)
            .ExecuteAffrowsAsync();

        _logger.LogInformation("更新系统配置: {ConfigKey} (敏感: {IsSensitive}), 是否需要重启: {RequiresRestart}",
            configKey, config.IsSensitive, config.RequiresRestart);

        // 通知节点配置变更
        if (_notificationService != null)
        {
            try
            {
                // TCP端口变更需要通知节点重新连接
                if (configKey == "TcpServerPort")
                {
                    await _notificationService.NotifyTcpPortChangedAsync(
                        int.Parse(configValue),
                        int.Parse(config.IsSensitive ? EncryptionHelper.Decrypt(oldValue) : oldValue));
                }
                // 控制面板API端口变更
                else if (configKey == "ControlApiPort")
                {
                    await _notificationService.NotifyControlApiPortChangedAsync(
                        int.Parse(configValue),
                        int.Parse(config.IsSensitive ? EncryptionHelper.Decrypt(oldValue) : oldValue));
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning(ex, "发送配置变更通知失败，但配置已更新: {ConfigKey}", configKey);
            }
        }

        return config.RequiresRestart;
    }

    /// <summary>
    /// 批量更新配置
    /// </summary>
    public async Task<Dictionary<string, bool>> UpdateConfigsAsync(
        Dictionary<string, string> configs,
        string? updatedBy = null)
    {
        var results = new Dictionary<string, bool>();

        foreach (var kvp in configs)
        {
            try
            {
                var requiresRestart = await UpdateConfigAsync(kvp.Key, kvp.Value, updatedBy);
                results[kvp.Key] = requiresRestart;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新配置失败: {ConfigKey}", kvp.Key);
                throw;
            }
        }

        return results;
    }

    /// <summary>
    /// 创建自定义配置
    /// </summary>
    public async Task<SystemConfig> CreateConfigAsync(
        string configKey,
        string configValue,
        string configType = "String",
        string? category = null,
        string? description = null,
        bool requiresRestart = false,
        bool isSensitive = false,
        string? createdBy = null)
    {
        var existing = await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.ConfigKey == configKey)
            .FirstAsync();

        if (existing != null)
        {
            throw new InvalidOperationException("配置键已存在");
        }

        // 验证值的类型
        if (!ValidateConfigValue(configType, configValue))
        {
            throw new InvalidOperationException($"配置值类型不匹配，期望类型：{configType}");
        }

        // 如果是敏感信息，加密存储
        var valueToStore = isSensitive ? EncryptionHelper.Encrypt(configValue) : configValue;

        var config = new SystemConfig
        {
            ConfigKey = configKey,
            ConfigValue = valueToStore,
            ConfigType = configType,
            Category = category,
            Description = description,
            RequiresRestart = requiresRestart,
            IsSensitive = isSensitive,
            IsSystem = false,
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };

        await _dbProvider.Orm.Insert(config).ExecuteAffrowsAsync();
        _logger.LogInformation("创建自定义配置: {ConfigKey} = {ConfigValue} (敏感: {IsSensitive})",
            configKey, isSensitive ? "********" : configValue, isSensitive);

        return config;
    }

    /// <summary>
    /// 删除配置
    /// </summary>
    public async Task DeleteConfigAsync(string configKey)
    {
        var config = await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.ConfigKey == configKey)
            .FirstAsync();

        if (config == null)
        {
            throw new InvalidOperationException("配置不存在");
        }

        if (config.IsSystem)
        {
            throw new InvalidOperationException("系统配置不允许删除");
        }

        await _dbProvider.Orm.Delete<SystemConfig>()
            .Where(c => c.ConfigKey == configKey)
            .ExecuteAffrowsAsync();

        _logger.LogInformation("删除配置: {ConfigKey}", configKey);
    }

    /// <summary>
    /// 验证配置值类型
    /// </summary>
    private bool ValidateConfigValue(string configType, string configValue)
    {
        return configType switch
        {
            "Int" => int.TryParse(configValue, out _),
            "Bool" => bool.TryParse(configValue, out _),
            "String" => true,
            "Json" => true, // 可以进一步验证 JSON 格式
            _ => true
        };
    }

    /// <summary>
    /// 判断是否为端口配置
    /// </summary>
    private bool IsPortConfig(string configKey)
    {
        return configKey.EndsWith("Port", StringComparison.OrdinalIgnoreCase);
    }

    /// <summary>
    /// 验证端口配置
    /// </summary>
    private void ValidatePortConfig(string configKey, string configValue)
    {
        if (!int.TryParse(configValue, out var port))
        {
            throw new InvalidOperationException($"端口号必须是整数");
        }

        // 1. 验证端口范围
        if (!PortUtility.IsValidPort(port))
        {
            throw new InvalidOperationException($"端口号必须在 1-65535 范围内，当前值: {port}");
        }

        // 2. 推荐端口范围警告
        if (!PortUtility.IsRecommendedPort(port))
        {
            _logger.LogWarning("端口 {Port} 在系统保留范围内（1-1023），建议使用 1024-65535 范围内的端口", port);
        }

        // 3. 检查端口是否被占用
        if (!PortUtility.IsPortAvailable(port))
        {
            var portOwner = PortUtility.GetPortOwner(port);
            throw new InvalidOperationException($"端口 {port} 已被占用。{portOwner}。请选择其他端口或停止占用该端口的进程。");
        }

        _logger.LogInformation("端口验证通过: {ConfigKey} = {Port}", configKey, port);
    }

    /// <summary>
    /// 获取需要重启的配置列表
    /// </summary>
    public async Task<List<SystemConfig>> GetConfigsRequiringRestartAsync()
    {
        return await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.RequiresRestart)
            .OrderBy(c => c.Category)
            .OrderBy(c => c.SortOrder)
            .ToListAsync();
    }

    /// <summary>
    /// 获取解密后的配置值（仅用于敏感信息）
    /// </summary>
    public async Task<string?> GetDecryptedValueAsync(string configKey)
    {
        var config = await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.ConfigKey == configKey)
            .FirstAsync();

        if (config == null)
        {
            return null;
        }

        // 如果是敏感信息，解密返回；否则直接返回
        return config.IsSensitive ? EncryptionHelper.Decrypt(config.ConfigValue) : config.ConfigValue;
    }

    /// <summary>
    /// 批量获取解密后的配置值
    /// </summary>
    public async Task<Dictionary<string, string>> GetDecryptedValuesByCategoryAsync(string category)
    {
        var configs = await _dbProvider.Orm.Select<SystemConfig>()
            .Where(c => c.Category == category)
            .ToListAsync();

        var result = new Dictionary<string, string>();
        foreach (var config in configs)
        {
            var value = config.IsSensitive
                ? EncryptionHelper.Decrypt(config.ConfigValue)
                : config.ConfigValue;
            result[config.ConfigKey] = value;
        }

        return result;
    }
}
